﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using OWLServer.persistencia.util;
using OWLServer.owl.tipos;
using OWLServer.persistencia.interfaces;
using NHibernate.Criterion;

namespace OWLServer.persistencia.ado
{
    /// <summary>
    /// Clase que gestiona las ontologías en la base de datos.
    /// </summary>
    class OntologiaADO : IfzOntologiaADO
    {
        #region Miembros de IfzOntologiaADO

        /// <summary>
        /// Elimina todas las ontologías de la base de datos.
        /// </summary>
        public void limpiar()
        {
            using (ISession sesion = UtilidadesNHibernate.OpenSession())
            using (ITransaction trans = sesion.BeginTransaction())
            {
                sesion.CreateQuery("delete from Ontologia").ExecuteUpdate();
                sesion.CreateQuery("delete from EspacioNombres").ExecuteUpdate();
                sesion.CreateQuery("delete from UnionClasesDisjuntas").ExecuteUpdate();
                trans.Commit();
            }
        }

        /// <summary>
        /// Agrega una ontología a la base de datos
        /// </summary>
        /// <param name="ontologia">Ontología a agregar</param>
        public void agregar(Ontologia ontologia)
        {
            using (ISession sesion = UtilidadesNHibernate.OpenSession())
            using (ITransaction trans = sesion.BeginTransaction())
            {
                sesion.Save(ontologia);
                trans.Commit();
            }
        }

        /// <summary>
        /// Actualiza una ontología en la base de datos.
        /// </summary>
        /// <param name="ontologia">Ontología que hemos actualizado.</param>
        public void actualizar(Ontologia ontologia)
        {
            using (ISession sesion = UtilidadesNHibernate.OpenSession())
            using (ITransaction trans = sesion.BeginTransaction())
            {
                sesion.Update(ontologia);
                trans.Commit();
            }
        }

        /// <summary>
        /// Elimina una ontología de la base de datos.
        /// </summary>
        /// <param name="ontologia">Ontología a eliminar</param>
        public void eliminar(Ontologia ontologia)
        {
            using (ISession sesion = UtilidadesNHibernate.OpenSession())
            using (ITransaction trans = sesion.BeginTransaction())
            {
                IQuery consulta = sesion.CreateQuery("delete from Ontologia where IdBBDD = :var1");
                consulta.SetInt32("var1", ontologia.IdBBDD);
                consulta.ExecuteUpdate();
                trans.Commit();
            }
        }

        /// <summary>
        /// Obtiene una ontología a partir de si Identificador en la base de datos
        /// </summary>
        /// <param name="idOntologia">Identificador de la ontología</param>
        /// <param name="completa">Indica si se recuperán todos los datos de la ontología de la base de datos.</param>
        /// <returns>Ontología recuperada</returns>
        public Ontologia getOntologiaPorId(int idOntologia, bool completa)
        {
            Ontologia ontologia = null;
            using (ISession sesion = UtilidadesNHibernate.OpenSession())
            {
                ontologia = sesion.Get<Ontologia>(idOntologia);
                if (completa)
                {
                    NHibernateUtil.Initialize(ontologia.Clases);
                    NHibernateUtil.Initialize(ontologia.EspaciosNombres);
                    NHibernateUtil.Initialize(ontologia.Importadas);
                    NHibernateUtil.Initialize(ontologia.Individuos);
                    NHibernateUtil.Initialize(ontologia.PropiedadesDatos);
                    NHibernateUtil.Initialize(ontologia.PropiedadesObjetos);
                }
            }
            return ontologia;
        }

        /// <summary>
        /// Obtiene una ontología a partir de si Identificador
        /// </summary>
        /// <param name="idNombreOntologia">Identificador de la ontología</param>
        /// <param name="completa">Indica si se recuperán todos los datos de la ontología de la base de datos.</param>
        /// <returns>Ontología recuperada</returns>
        public IList<Ontologia> getOntologiaPorIdNombre(string idNombreOntologia, bool completa)
        {
            IList<Ontologia> ontologias;
            using (ISession sesion = UtilidadesNHibernate.OpenSession())
            {
                IQuery consulta = sesion.CreateQuery("from Ontologia o where o.Id = :var1");
                consulta.SetString("var1", idNombreOntologia);
                ontologias = consulta.List<Ontologia>();
                if (completa)
                {
                    foreach (Ontologia ontologia in ontologias)
                    {
                        NHibernateUtil.Initialize(ontologia.Clases);
                        NHibernateUtil.Initialize(ontologia.EspaciosNombres);
                        NHibernateUtil.Initialize(ontologia.Importadas);
                        NHibernateUtil.Initialize(ontologia.Individuos);
                        NHibernateUtil.Initialize(ontologia.PropiedadesDatos);
                        NHibernateUtil.Initialize(ontologia.PropiedadesObjetos);
                    }
                }
            }
            return ontologias;
        }

        /// <summary>
        /// Obtiene una ontología a partir de si Identificador
        /// </summary>
        /// <param name="espacioNombrePrincipal">Identificador de espacio Nombre Principal de la ontología</param>
        /// <param name="completa">Indica si se recuperán todos los datos de la ontología de la base de datos.</param>
        /// <returns>Ontología recuperada</returns>
        public Ontologia getOntologiaEspacioNombrePrincipal (string espacioNombrePrincipal, bool completa)
        {
            Ontologia ontologia;
            using (ISession sesion = UtilidadesNHibernate.OpenSession())
            {
                IQuery consulta = sesion.CreateQuery("from Ontologia o where o.EspacioNombresPrincipal.Uri = :var1");
                consulta.SetString("var1", espacioNombrePrincipal);
                ontologia = consulta.UniqueResult<Ontologia>();
                if (ontologia != null && completa)
                {
                    NHibernateUtil.Initialize(ontologia.Clases);
                    NHibernateUtil.Initialize(ontologia.EspaciosNombres);
                    NHibernateUtil.Initialize(ontologia.Importadas);
                    NHibernateUtil.Initialize(ontologia.Individuos);
                    NHibernateUtil.Initialize(ontologia.PropiedadesDatos);
                    NHibernateUtil.Initialize(ontologia.PropiedadesObjetos);
                }
            }
            return ontologia;
        }

        /// <summary>
        /// Ontiene una ontología a partir de su espacio de nombres principal
        /// </summary>
        /// <param name="espacioPrincipal">Espacio de nombre principal que define la ontología.</param>
        /// <param name="completa">Indica si se recuperán todos los datos de la ontología de la base de datos.</param>
        /// <returns>Ontología recuperada</returns>
        public Ontologia getOntologiaPorEspacioNombrePrincipal(EspacioNombres espacioPrincipal, bool completa)
        {
            Ontologia ontologia = null;
            using (ISession sesion = UtilidadesNHibernate.OpenSession())
            {
                IQuery consulta = sesion.CreateQuery("from Ontologia o where o.EspacioNombresPrincipal.Uri = :var1");
                consulta.SetString("var1", espacioPrincipal.Uri);
                ontologia = consulta.UniqueResult<Ontologia>();
                if (ontologia != null && completa)
                {
                    NHibernateUtil.Initialize(ontologia.Clases);
                    NHibernateUtil.Initialize(ontologia.EspaciosNombres);
                    NHibernateUtil.Initialize(ontologia.Importadas);
                    NHibernateUtil.Initialize(ontologia.Individuos);
                    NHibernateUtil.Initialize(ontologia.PropiedadesDatos);
                    NHibernateUtil.Initialize(ontologia.PropiedadesObjetos);
                }
            }
            return ontologia;
        }

        /// <summary>
        /// Nos devuelve la lista de ontologías de la base de datos.
        /// </summary>
        /// <param name="completa">Indica si se recuperán todos los datos de las ontologías de la base de datos.</param>
        /// <returns>Lista de ontologías recuperadas</returns>
        public IList<Ontologia> getListOntologias(bool completa)
        {
            IList<Ontologia> ontologias;
            using (ISession sesion = UtilidadesNHibernate.OpenSession())
            {
                ICriteria criterio = sesion.CreateCriteria(typeof(Ontologia));
                ontologias = criterio.List<Ontologia>();
                if (ontologias != null && completa)
                {
                    foreach (Ontologia ontologia in ontologias)
                    {
                        NHibernateUtil.Initialize(ontologia.Clases);
                        NHibernateUtil.Initialize(ontologia.EspaciosNombres);
                        NHibernateUtil.Initialize(ontologia.Importadas);
                        NHibernateUtil.Initialize(ontologia.Individuos);
                        NHibernateUtil.Initialize(ontologia.PropiedadesDatos);
                        NHibernateUtil.Initialize(ontologia.PropiedadesObjetos);
                    }
                }
            }
            return ontologias;
        }

        #endregion
    }
}

